﻿#include "qcustomplotdemo1.h"
#include "ui_qcustomplotdemo1.h"

QCustomPlotDemo1::QCustomPlotDemo1(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QCustomPlotDemo1)
{
    ui->setupUi(this);

    axis_x_mid=(axis_x_max-axis_x_min)*0.5;
    axis_y_mid=(axis_y_max-axis_y_min)*0.5;

    //手动挡
    VMasHand_x.clear();
    VMasHand_y.clear();
    VMasHand_x.insert(0,0);
    VMasHand_y.insert(0,0);
    VMasHand_x.insert(1,10);
    VMasHand_y.insert(1,0);
    VMasHand_x.insert(2,14);
    VMasHand_y.insert(2,15);
    VMasHand_x.insert(3,22);
    VMasHand_y.insert(3,15);
    VMasHand_x.insert(4,24);
    VMasHand_y.insert(4,10);
    VMasHand_x.insert(5,27);
    VMasHand_y.insert(5,0);
    VMasHand_x.insert(6,48);
    VMasHand_y.insert(6,0);
    VMasHand_x.insert(7,53);
    VMasHand_y.insert(7,15);
    VMasHand_x.insert(8,55);
    VMasHand_y.insert(8,15);
    VMasHand_x.insert(9,60);
    VMasHand_y.insert(9,32);
    VMasHand_x.insert(10,84);
    VMasHand_y.insert(10,32);
    VMasHand_x.insert(11,92);
    VMasHand_y.insert(11,10);
    VMasHand_x.insert(12,95);
    VMasHand_y.insert(12,0);
    VMasHand_x.insert(13,116);
    VMasHand_y.insert(13,0);
    VMasHand_x.insert(14,121);
    VMasHand_y.insert(14,15);
    VMasHand_x.insert(15,123);
    VMasHand_y.insert(15,15);
    VMasHand_x.insert(16,132);
    VMasHand_y.insert(16,35);
    VMasHand_x.insert(17,134);
    VMasHand_y.insert(17,35);
    VMasHand_x.insert(18,142);
    VMasHand_y.insert(18,50);
    VMasHand_x.insert(19,154);
    VMasHand_y.insert(19,50);
    VMasHand_x.insert(20,162);
    VMasHand_y.insert(20,35);
    VMasHand_x.insert(21,175);
    VMasHand_y.insert(21,35);
    VMasHand_x.insert(22,177);
    VMasHand_y.insert(22,32);
    VMasHand_x.insert(23,184);
    VMasHand_y.insert(23,10);
    VMasHand_x.insert(24,187);
    VMasHand_y.insert(24,0);
    VMasHand_x.insert(25,195);
    VMasHand_y.insert(25,0);
    //自动挡
    VMasAutoP_x.clear();
    VMasAutoP_y.clear();
    VMasAutoP_x.insert(0, 0);
    VMasAutoP_y.insert(0, 0);
    VMasAutoP_x.insert(1, 10);
    VMasAutoP_y.insert(1, 0);
    VMasAutoP_x.insert(2, 14);
    VMasAutoP_y.insert(2, 15);
    VMasAutoP_x.insert(3, 22);
    VMasAutoP_y.insert(3, 15);
    VMasAutoP_x.insert(4, 27);
    VMasAutoP_y.insert(4, 0);
    VMasAutoP_x.insert(5, 48);
    VMasAutoP_y.insert(5, 0);
    VMasAutoP_x.insert(6, 60);
    VMasAutoP_y.insert(6, 32);
    VMasAutoP_x.insert(7, 84);
    VMasAutoP_y.insert(7, 32);
    VMasAutoP_x.insert(8, 95);
    VMasAutoP_y.insert(8, 0);
    VMasAutoP_x.insert(9, 116);
    VMasAutoP_y.insert(9, 0);
    VMasAutoP_x.insert(10, 142);
    VMasAutoP_y.insert(10, 50);
    VMasAutoP_x.insert(11, 154);
    VMasAutoP_y.insert(11, 50);
    VMasAutoP_x.insert(12, 162);
    VMasAutoP_y.insert(12, 35);
    VMasAutoP_x.insert(13, 175);
    VMasAutoP_y.insert(13, 35);
    VMasAutoP_x.insert(14, 187);
    VMasAutoP_y.insert(14, 0);
    VMasAutoP_x.insert(15, 195);
    VMasAutoP_y.insert(15, 0);

    labStr[0] = QString("开始检测");
    labStr[1] = QString("请挂一档");
    labStr[2] = QString("离合器脱开");
    labStr[3] = QString("请挂一档");
    labStr[4] = QString("请挂二档");
    labStr[5] = QString("减速，离合器脱开");
    labStr[6] = QString("请挂一档");
    labStr[7] = QString("请挂二档");
    labStr[8] = QString("请挂三档");
    labStr[9] = QString("减至二档");
    labStr[10] = QString("减速，离合器脱开");
    labStr[11] = QString("结束检测，拔出采样气管");

    labAxis[0][0] = 0; // 第1个提示语的x,y坐标
    labAxis[0][1] = 0;
    labAxis[1][0] = 8; // 第2个提示语的x,y坐标
    labAxis[1][1] = 0;
    labAxis[2][0] = 24;
    labAxis[2][1] = 10;
    labAxis[3][0] = 46;
    labAxis[3][1] = 0;
    labAxis[4][0] = 53;
    labAxis[4][1] = 15;
    labAxis[5][0] = 92;
    labAxis[5][1] = 10;
    labAxis[6][0] = 114;
    labAxis[6][1] = 0;
    labAxis[7][0] = 121;
    labAxis[7][1] = 15;
    labAxis[8][0] = 132;
    labAxis[8][1] = 35;
    labAxis[9][0] = 175;
    labAxis[9][1] = 35;
    labAxis[10][0] = 184;
    labAxis[10][1] = 10;
    labAxis[11][0] = 195; // 第10个提示语的x,y坐标
    labAxis[11][1] = 0;
    InitPlot();
}

QCustomPlotDemo1::~QCustomPlotDemo1()
{
    delete ui;
}

void QCustomPlotDemo1::InitPlot(bool isAuto)
{
    vmasPlot=ui->customPlot;
    vmasPlot->setBackground(QBrush(QColor(41,37,82)));//背景色
    vmasPlot->setOpenGl(true,195000);
    vmasPlot->xAxis->grid()->setVisible(false);
    vmasPlot->xAxis->setRange(axis_x_min,axis_x_max);//坐标
    vmasPlot->xAxis->setLabel("时间(10ms)");
    vmasPlot->xAxis->setBasePen(QPen(Qt::white,2));// x轴线的画笔颜色和粗细
    vmasPlot->xAxis->setTickPen(QPen(Qt::white,2));// x轴线上的主刻度线（有数字的刻度线）的画笔颜色和粗细
    vmasPlot->xAxis->setTickLabelColor(Qt::green);// x轴线上的主刻度线下的文字颜色
    vmasPlot->xAxis->setTickLengthIn(20);// 轴线内主刻度线的长度 设置向内刻度的长度（以像素为单位）
    vmasPlot->xAxis->setTickLengthOut(20);// 轴线外主刻度线的长度 设置向外刻度的长度（以像素为单位）。
    vmasPlot->xAxis->setSubTickPen(QPen(QColor(220,20,60),1));//粉红色，x轴线上的子刻度线（有数字的刻度线）的画笔颜色和粗细
    vmasPlot->xAxis->setLabelColor(Qt::red);// 只有设置了标签，轴标签的颜色才会显示
    //vmasPlot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);// 设置轴线结束时的风格为 实角三角形但内部有凹陷的形状
    //vmasPlot->xAxis->setLowerEnding(QCPLineEnding::esDisc);//setLowerEnding设置轴线开始时的风格

    vmasPlot->yAxis->grid()->setVisible(false);
    vmasPlot->yAxis->setRange(axis_y_min,axis_y_max);//坐标
    vmasPlot->yAxis->setBasePen(QPen(Qt::white,2));// x轴线的画笔颜色和粗细
    vmasPlot->yAxis->setTickPen(QPen(Qt::white,2));// x轴线上的主刻度线（有数字的刻度线）的画笔颜色和粗细
    vmasPlot->yAxis->setTickLabelColor(Qt::green);// x轴线上的主刻度线下的文字颜色
    vmasPlot->yAxis->setTickLengthIn(4);// 轴线内主刻度线的长度
    vmasPlot->yAxis->setTickLengthOut(6);// 轴线外主刻度线的长度
    vmasPlot->yAxis->setSubTickPen(QPen(QColor(220,20,60),1));//粉红色，x轴线上的子刻度线（有数字的刻度线）的画笔颜色和粗细
    vmasPlot->yAxis->setLabelColor(Qt::red);// 只有设置了标签，轴标签的颜色才会显示

    for (int i=0;i<graphInd::grapEnd;i++) //增加6个图表，代表6条曲线
        vmasPlot->addGraph(vmasPlot->xAxis,vmasPlot->yAxis);

    vmasPlot->graph(nowForce)->setVisible(false); // 隐藏实时扭力和功率图表
    vmasPlot->graph(nowPower)->setVisible(false);

    circle=new QCPItemEllipse(vmasPlot);//增加指引圆圈
    QPen pen(Qt::green, 8, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
    circle->setPen(pen);
    //圆心C(x, y) 半径r
    //tL(x-r, y+r) bR(x+r, y-r)
    // 一个椭圆 它有两个位置，左上和右下，它们定义了椭圆将被绘制的矩形。
    circle->topLeft->setCoords(-R*0.4, R);      //左上角位置 tL
    circle->bottomRight->setCoords(R*0.4, -R);  //右下角位置 bR

    QVector<double> dnVMas_y;
    QVector<double> upVMas_y;
    QVector<double> stdVMas_y;
    QVector<double> stdVMas_x;
    QVector<double> VMas_x=isAuto?VMasAutoP_x:VMasHand_x;
    QVector<double> VMas_y=isAuto?VMasAutoP_y:VMasHand_y;
    for (int i=0;i<VMas_x.count();i++)
    {
        double up=VMas_y.at(i)+3; // 用于画速度上限和下限的y坐标
        double dn=VMas_y.at(i)-3;
        dnVMas_y.insert(i,dn);
        upVMas_y.insert(i,up);
    }
    int allspeed = 0;
    double speedstep = 0;

    for (int i = 1; i < VMas_x.count(); i++)
    {
        // 画速度标准线
        allspeed = int((VMas_x.at(i) - VMas_x.at(i-1)) * 100); // 相连两个x坐标之间的点数 假如i=1，那就是（10-0）*100=1000ms
        if (VMas_x.at(i) > VMas_x.at(i-1))
            speedstep = (VMas_y.at(i) - VMas_y.at(i-1)) / (VMas_x.at(i) - VMas_x.at(i-1)) / 100.0; // 斜率缩小100倍
        else
            speedstep = 0;
        for (int j = 0; j < allspeed; j++)
            vmasPlot->graph(stdMid)->addData(VMas_x.at(i-1) + j / 100.0, VMas_y.at(i-1) + speedstep * j);

        // 画速度上限线
        allspeed = int((VMas_x.at(i) - VMas_x.at(i-1)) * 100);
        if (VMas_x.at(i) > VMas_x.at(i-1))
            speedstep = (upVMas_y.at(i) - upVMas_y.at(i-1)) / (VMas_x.at(i) - VMas_x.at(i-1)) / 100.0;
        else
            speedstep = 0;
        for (int j = 0; j < allspeed; j++)
            vmasPlot->graph(stdUp)->addData(VMas_x.at(i-1) + j / 100.0, upVMas_y.at(i-1) + speedstep * j);

        // 画速度下限线
        allspeed = int((VMas_x.at(i) - VMas_x.at(i-1)) * 100.0);
        if (VMas_x.at(i) > VMas_x.at(i-1))
            speedstep = (dnVMas_y.at(i) - dnVMas_y.at(i-1)) / (VMas_x.at(i) - VMas_x.at(i-1)) / 100.0;
        else
            speedstep = 0;
        for (int j = 0; j < allspeed; j++)
            vmasPlot->graph(stdDn)->addData(VMas_x.at(i-1) + j / 100.0, dnVMas_y.at(i-1) + speedstep * j);
    }
    vmasPlot->graph(stdMid)->setPen(QPen(Qt::green,2));
    vmasPlot->graph(stdDn)->setPen(QPen(Qt::yellow,5));
    vmasPlot->graph(stdUp)->setPen(QPen(Qt::yellow,5));
    vmasPlot->graph(stdUp)->setBrush(QBrush(QColor(125, 125, 125),Qt::BrushStyle::SolidPattern));
    vmasPlot->graph(stdUp)->setChannelFillGraph(vmasPlot->graph(stdDn)); // 设置上下限之间填充的颜色

    vmasPlot->graph(nowSpeed)->setPen(QPen(Qt::white,2));
    //vmasPlot->legend->setSelectableParts(QCPLegend::spNone);
    DrawLab(isAuto);
    vmasPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
    vmasPlot->replot();
}

void QCustomPlotDemo1::DrawLab(bool isAuto)
{
    labText=new QCPItemText*[12];
    labLine=new QCPItemLine*[12];
    for (int i=0;i<12;i++) {
        labLine[i]=new QCPItemLine(vmasPlot);
        labText[i]=new QCPItemText(vmasPlot);

        labText[i]->setPositionAlignment(Qt::AlignTop|Qt::AlignLeft);//文字布局：顶、左对齐
        labText[i]->position->setType(QCPItemPosition::ptPlotCoords);//位置类型（当前轴范围的比例为单位/实际坐标为单位）
        labText[i]->setFont(QFont(font().family(), 30,QFont::Weight::Bold, true)); //字体大小
        labText[i]->setPen(QPen(Qt::black,0.01)); //字体颜色
        labText[i]->setColor(QColor(Qt::yellow));
        labText[i]->setPadding(QMargins(2,2,2,2));//文字距离边框几个像素
        switch (i) {
        case 1:
        case 3:
        case 4:
        case 6:
        case 7:
        case 8:
        case 11:
            labText[i]->position->setCoords(labAxis[i][0]-2, labAxis[i][1]+12);
            labLine[i]->start->setCoords(labAxis[i][0], labAxis[i][1]+10);
            break;
        default:
            labText[i]->position->setCoords(labAxis[i][0], labAxis[i][1]+8);
            labLine[i]->start->setCoords(labAxis[i][0], labAxis[i][1]+6);
            //labLine[i]->start->setParentAnchor(labText[i]->bottomLeft);
            break;
        }
        labText[i]->setText(QString(labStr[i]));
        labLine[i]->setHead(QCPLineEnding::esNone);//设置箭头类型（三角形、菱形、方形等）
        labLine[i]->setPen(QPen(Qt::white,3));
        labLine[i]->end->setCoords(labAxis[i][0], labAxis[i][1]); //设置直线终点为坐标系中的点
    }
    for (int i=1;i<11;i++)
    {
        labText[i]->setVisible(!isAuto);
        labLine[i]->setVisible(!isAuto);
    }
}

void QCustomPlotDemo1::DrawLine(QList<SamplingDataItem> curve,int len)
{
    if(len>0)
    {
        QVector<double> speedVector;
        QVector<double> xVector;
        speedVector.clear();
        for (int i=0;i<len;i++) {
            if(xValues>=maxPoints)
                break;
            xVector.append(xValues++*0.01);
            speedVector.append(curve.at(i).Speed);
        }
        double _xx=xVector.last();
        double _yy=speedVector.last();
        circle->topLeft->setCoords(_xx-R*0.4,_yy+ R);      //左上角位置 tL
        circle->bottomRight->setCoords(_xx+R*0.4, _yy-R);  //右下角位置 bR
        vmasPlot->graph(nowSpeed)->addData(xVector,speedVector);

        if(_xx>=axis_x_mid)//移动x坐标
        {
            vmasPlot->xAxis->setRange(_xx-axis_x_mid,_xx+axis_x_mid);
            //qDebug()<< QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss:zzz")<< x;
        }
        if(_yy>=axis_y_mid)//移动y坐标
        {
            vmasPlot->yAxis->setRange(_yy-axis_y_mid,_yy+axis_y_mid);
        }
        else if(_yy<=axis_y_mid)//移动y坐标
        {
            vmasPlot->yAxis->setRange(axis_y_min,axis_y_max);
        }
        if(qAbs( _yy-GetNowStdSpeed(xValues-1))>3.0&&!mutualColor) // 如果速度超出上下限范围，则改变指引圆圈颜色
        {
            circle->setPen(QPen(Qt::red, 8, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            mutualColor=true;
        }
        else{
            circle->setPen(QPen(Qt::green, 8, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            mutualColor=false;
        }
        vmasPlot->replot();
    }
}

double QCustomPlotDemo1::GetNowStdSpeed(int ind)
{
    if(ind<=0||ind>=maxPoints)
        ind=xValues;
    ind=qMax(0,ind);
    ind=qMin(maxPoints,ind);
    return vmasPlot->graph(stdMid)->dataMainValue(ind);
}

void QCustomPlotDemo1::ClearLine()
{
    vmasPlot->graph(nowSpeed)->data().data()->clear();
    vmasPlot->graph(nowForce)->data().data()->clear();
    vmasPlot->graph(nowPower)->data().data()->clear();
    vmasPlot->xAxis->setRange(axis_x_min,axis_x_max);//X坐标
    vmasPlot->yAxis->setRange(axis_y_min,axis_y_max);//Y坐标
    vmasPlot->replot();
}
